package com.ecar.api.support.util;

import com.ecar.common.datetime.TimeUtil;
import com.ecar.common.util.StringUtil;
import redis.clients.jedis.Jedis;

import java.net.InetAddress;
import java.util.Date;

/**
 * 生成16个字符的唯一ID
 * Created by admin on 2016/6/26.
 */
public class UniqueID {

	// 集群中的机器代码，2位16进制数，最多支持256个
	private static String machineId = "01";
	private static volatile int index = 0;        // 自增序列
	private static final long OFFSET = 1451577600000L;
	private static String hostname = null;

	static {
		String mid = Props.getValue("cluster.machine.id");
		if (StringUtil.isNotEmpty(mid)) {
			machineId = mid;
		}
	}

	public static String getMachineId() {
		if (StringUtil.isEmpty(hostname)) {
			try (Jedis jedis = Redis.getResource()){
				String key = "clusters:machines";
				InetAddress addr = InetAddress.getLocalHost();
				hostname = addr.getHostName();
				if (StringUtil.isNotEmpty(hostname)) {
					String mid = jedis.hget(key, hostname);
					if (StringUtil.isEmpty(mid)) {
						long m = jedis.hlen(key) + 1;
						machineId = String.format("%02d", m);
						jedis.hset(key, hostname, machineId);
					}
					System.out.println("====================================================");
					System.out.println("    host: " + hostname + ", machine: " + machineId);
					System.out.println("====================================================");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return machineId;
	}

	public static void setMachineId(String machineId) {
		UniqueID.machineId = machineId;
	}

	/**
	 * 生成大写的16字符的唯一标识，机器代码(2位16进制字符)+秒数(当前时间总秒数的16进制数)+序列(5位16进制字符)
	 * 支持每秒 0xFFFFF个并发
	 * @return
	 */

	public static synchronized String generate() {
		long time = System.currentTimeMillis() / 1000;
		String unique = getMachineId() + String.format("%09X", time) + String.format("%05X", index);
		if (++index > 0xFFFFF) index = 0;
		return unique.toUpperCase();
	}

	/**
	 * 生成大写的16字符的唯一标识，站点编号(2位)+机器代码(2位)+秒数(当前时间总秒数的16进制数)+序列(5位16进制字符)
	 * 支持每秒 0xFFFFF 个并发
	 * @return
	 */
	public static synchronized String generate(String stationNo) {
		if (StringUtil.isEmpty(stationNo)) stationNo = "00";
		stationNo = stationNo.length() == 1 ? "0" + stationNo : stationNo.length() == 2 ? stationNo : "00";

		long time = (System.currentTimeMillis() - OFFSET) / 1000;
		time = Long.parseLong(String.valueOf(time).substring(1));

		String unique = stationNo + getMachineId() + String.format("%07X", time) + String.format("%05X", index);
		if (++index > 0xFFFFF) index = 0;
		return unique.toUpperCase();
	}

	public static synchronized String batchNo(String orderNo) {
		int ret = index;
		if (++index > 0xFFFFF) index = 0;
		return TimeUtil.formatTime(new Date(), "yyyyMMdd") + orderNo + String.format("%06X", ret);
	}

	public static synchronized String getIndex() {
		int ret = index;
		if (++index > 0xFFFFF) index = 0;
		return String.format("%05X", ret);
	}
}
